package org.terramagnet.mvcframework;

import org.terramagnet.mvcframework.friendly.Friendly;
import java.util.IllegalFormatException;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
import org.terramagnet.mvcframework.friendly.I18nFriendly;
import org.terramagnet.mvcframework.http.HttpStatusException;

/**
 * 系统异常封装.
 *
 * @author lip
 */
public class ApplicationRuntimeException extends RuntimeException implements FriendlyException {

    /**
     * 异常说明. 用户友好信息。
     */
    private final Friendly friendly;
    /**
     * 异常友好化信息的参数.
     */
    private final Object[] friendlyParams;

    public ApplicationRuntimeException(Friendly friendly, Object... params) throws IllegalFormatException {
        super(friendly.toFriendly(Locale.getDefault(), params));
        this.friendly = friendly;
        this.friendlyParams = params;
    }

    public ApplicationRuntimeException(Throwable cause, Friendly friendly, Object... params) throws IllegalFormatException {
        super(friendly.toFriendly(Locale.getDefault(), params), cause);
        this.friendly = parseFriendly(cause, friendly);
        this.friendlyParams = params;
    }

    public ApplicationRuntimeException(String message, Friendly friendly, Object... params) throws IllegalFormatException {
        super(message);
        this.friendly = friendly;
        this.friendlyParams = params;
    }

    public ApplicationRuntimeException(String message, Throwable cause, Friendly friendly, Object... params) throws IllegalFormatException {
        super(message, cause);
        this.friendly = parseFriendly(cause, friendly);
        this.friendlyParams = params;
    }

    public ApplicationRuntimeException(int code, String message) {
        super(message);
        this.friendly = I18nFriendly.DEFAULT;
        this.friendlyParams = null;
    }

    public ApplicationRuntimeException(String message, Throwable cause) {
        super(message);
        this.friendly = parseFriendly(cause, "");
        this.friendlyParams = null;
    }

    public ApplicationRuntimeException(int code, String message, Throwable cause) {
        super(message, cause);
        this.friendly = parseFriendly(cause, "");
        this.friendlyParams = null;
    }

    public ApplicationRuntimeException(int code, String message, String friendly, Object... params) {
        super(message);
        this.friendly = new I18nFriendly(code, friendly);
        this.friendlyParams = params;
    }

    public ApplicationRuntimeException(String message, Throwable cause, String friendly, Object... params) {
        super(message);
        this.friendly = parseFriendly(cause, friendly);
        this.friendlyParams = params;
    }

    public ApplicationRuntimeException(int code, String message, Throwable cause, String friendly, Object... params) {
        super(message, cause);
        this.friendly = parseFriendly(cause, friendly);
        this.friendlyParams = params;
    }

    /**
     * 异常代码.
     *
     * @return the code
     */
    @Override
    public int getCode() {
        return friendly.getCode();
    }

    @Override
    public String toFriendly(Locale locale) {
        return friendly.toFriendly(locale, friendlyParams);
    }

    private Friendly parseFriendly(Throwable cause, String friendly) {
        int code = 500;
        if (cause instanceof HttpStatusException) {
            HttpStatusException ex = (HttpStatusException) cause;
            code = ex.getStatus();
        }
        if (StringUtils.isBlank(friendly)) {
            friendly = I18nFriendly.DEFAULT.getTemplate();
        }
        return new I18nFriendly(code, friendly);
    }

    private Friendly parseFriendly(Throwable cause, Friendly defaultFriendly) {
        int code = 500;
        if (cause instanceof HttpStatusException) {
            HttpStatusException ex = (HttpStatusException) cause;
            code = ex.getStatus();
        }
        return new I18nFriendly(code, defaultFriendly.getTemplate());
    }
}
